<template>
  <a-button type="primary" @click="visible = true"> 上传 </a-button>

  <DraggableModal
    v-model:open="visible"
    title="上传"
    :width="800"
    ok-text="开始上传"
    :ok-button-props="{ disabled: disabledUpload }"
    @ok="onOk"
    @cancel="onCancel"
  >
    <a-flex justify="space-between" align="center">
      <a-alert
        message="单个文件不超过2MB，最多只能上传10个文件"
        type="info"
        show-icon
      />
      <a-upload
        :multiple="true"
        :before-upload="beforeUpload"
        :show-upload-list="false"
      >
        <a-button type="primary"> 选择文件 </a-button>
      </a-upload>
    </a-flex>

    <DynamicTable :search="false" :data-source="fileList" :columns="columns" />
  </DraggableModal>
</template>

<script setup lang="tsx">
import { ref, computed } from "vue";
import { message, type UploadProps } from "ant-design-vue";
import { UploadResultStatus, fileListColumns, type FileItem } from "./columns";
import { DraggableModal } from "@/components/core/draggable-modal";
import { useTable, type TableColumn } from "@/components/core/dynamic-table";
import Api from "@/api/backend/api";

const baseUrl = import.meta.env.VITE_BASE_OSS_URL;
const emit = defineEmits(["uploadSuccess"]);
const props = defineProps<{
  modelValue: string[];

}>();
const [DynamicTable] = useTable();

const fileList = ref<FileItem[]>([]);
watch(props.modelValue, (newVal) => {
  fileList.value = newVal.map((item) => {
    return {
      uid: Math.random().toString(36).substr(2, 9),
      name: item,
      status: UploadResultStatus.SUCCESS,
      percent: 100,
      thumbUrl: baseUrl + "/" + item,
    };
  });
  },
  {
    immediate: true,
    deep: true,
  }
);
const visible = ref(false);

const disabledUpload = computed(() => {
  return !fileList.value.some((n) => n.status !== UploadResultStatus.SUCCESS);
});
const fileToBase64 = (file: File): Promise<string> => {
  const { promise, resolve, reject } = Promise.withResolvers<string>();

  const reader = new FileReader();

  reader.onload = () => {
    resolve(reader.result as string);
  };
  reader.onerror = (error) => {
    reject(error);
  };

  reader.readAsDataURL(file);
  return promise;
};

const onCancel = () => {
  const hasSuccess = fileList.value.some(
    (n) => n.status === UploadResultStatus.SUCCESS
  );
  if (hasSuccess) {
    emit("uploadSuccess");
  }
  fileList.value = [];
};

const onOk = async () => {
    console.log(fileList.value);
  const uploadFileList = fileList.value.filter(
    (n) => n.status !== UploadResultStatus.SUCCESS
  );
  const result = [];
  await Promise.all(
    uploadFileList.map(async (item) => {
      try {
        const data = await Api.fileUpload.upload({ file: item.file });
        item.status = UploadResultStatus.SUCCESS;
        result.push(data);
      } catch (error) {
        item.status = UploadResultStatus.ERROR;
      }
    })
  );

  emit("uploadSuccess", result);
};

const beforeUpload: UploadProps["beforeUpload"] = async (file) => {
  if (file.size / 1024 / 1024 > 2) {
    message.error("单个文件不超过2MB");
  } else {
    const item: FileItem = {
      file,
      uid: file.uid,
      name: file.name,
      size: file.size,
      status: "",
      percent: 0,
      thumbUrl: await fileToBase64(file),
    };
    fileList.value.push(item);
  }

  return false;
};

const handleRemove = (record: FileItem) => {
  fileList.value = fileList.value.filter((n) => n.uid !== record.uid);
};

const columns: TableColumn<FileItem>[] = [
  ...fileListColumns,
  {
    width: 120,
    title: "操作",
    dataIndex: "ACTION",
    fixed: false,
    actions: ({ record }) => [
      {
        label: "删除",
        color: "red",
        onClick: () => handleRemove(record),
      },
    ],
  },
];
</script>

<style scoped></style>
